package com.itheima.tanhua.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.tanhua.api.*;
import com.itheima.tanhua.domain.*;
import com.itheima.tanhua.dto.AnswersDto;
import com.itheima.tanhua.exception.BusinessException;
import com.itheima.tanhua.utils.UserHolder;
import com.itheima.tanhua.vo.*;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author Lff
 * @date 2022/4/8
 */
@Service
public class TestSoulService {

    @DubboReference
    private QuestionnairesApi questionnairesApi;

    @DubboReference
    private ProblemsApi problemsApi;

    @DubboReference
    private AnswerApi answerApi;

    @DubboReference
    private ScoreApi scoreApi;

    @DubboReference
    private PersonalityApi personalityApi;


    @DubboReference
    private UserInfoApi userInfoApi;

    /**
     * 查询所有的问卷列表
     * [1,2,3,4,5,6,7,8]
     *
     * @return
     */
    public List<QuestionnaireVo> getQuestionnairesList() {
        //查询所有的问卷列表Questionnaires
        List<Questionnaire> questionnaireList = questionnairesApi.findAll();
        if (CollUtil.isEmpty(questionnaireList)) {
            return null;
        }

        //获取所有的试题 以Map格式返回
        // k-题目所属试卷id    v -> 试题集合
        //抽取题目ids 抽取试卷id
        List<Long> questionIds = CollUtil.getFieldValues(questionnaireList, "id", Long.class);
        List<String> problemIds = CollUtil.getFieldValues(questionnaireList, "problemIds", String.class);
        Map<Long, List<Problems>> problemsToMap = problemsApi.findProblemsToMap(questionIds, problemIds);
        //获取所有试题对应的答案 返回Map
        //其中 K--> 试题编号 v->答案集合
        Map<Long, List<Answer>> answerMap = answerApi.findAnswerToMap(problemIds);

        //获取用户最高通关记录id
        Score score = scoreApi.getMaxCheckPoint(UserHolder.getUser().getId());
        //构造返回对象
        List<QuestionnaireVo> results = new ArrayList<>();
        questionnaireList.forEach(questionnaire -> {
            QuestionnaireVo result = QuestionnaireVo.init(questionnaire);
            //填充题目列表vo [1,2,3,4,5,6]
            List<Problems> problems = problemsToMap.get(questionnaire.getId());
            List<ProblemsVo> problemsVos = new ArrayList<>();
            for (Problems problem : problems) {
                List<Answer> answers = answerMap.get(problem.getId());
                ProblemsVo problemsVo = ProblemsVo.init(problem, answers);
                problemsVos.add(problemsVo);
            }
            Collections.shuffle(problemsVos);
            result.setQuestions(problemsVos);
            //检验是否解锁
            Integer checkpoints = (questionnaire.getLevel() * 10) + questionnaire.getStars();
            if (score != null) {
                //判断当前关卡是否大于用户的最大关卡
                if (checkpoints <= score.getCheckpoints()) {
                    //已解锁
                    result.setIsLock(0);
                    //填充最新报告id
                    Score s = scoreApi.findByUserIdAndCheckPoint(UserHolder.getUser().getId(), checkpoints);
                    String reportId = s == null ? null : s.getPersonalityId().toString();
                    result.setReportId(reportId);
                } else {
                    Integer nextPoint = 0;
                    if (score.getStars() == 3 && score.getLevel() < 3) {
                        nextPoint = (score.getLevel() + 1) * 10 + 1;
                    } else if (score.getStars() < 3 && score.getLevel() <= 3) {
                        nextPoint = score.getCheckpoints() + 1;
                    }
                    if (checkpoints == nextPoint) {
                        result.setIsLock(0);//解锁
                        result.setReportId(null); //暂无报告id
                    }
                }
            } else {
                //始终开放第一关
                if (checkpoints == 11) {
                    //score为null
                    result.setIsLock(0);//解锁
                    result.setReportId(null); //暂无报告id
                }
            }
            results.add(result);
        });
        String s = JSON.toJSONString(results);
        System.out.println(s);
        return results;
    }


    /**
     * 用户提交结果
     */

    public String subTestSoul(List<AnswersDto> answersDtos) {
        //试题id
        List<Long> questionIdList = CollUtil.getFieldValues(answersDtos, "questionId", Long.class);
        //答案id
        List<Long> optionIds = CollUtil.getFieldValues(answersDtos, "optionId", Long.class);
        //处理好试题id
        Long[] idsArr = ArrayUtil.toArray(questionIdList, Long.class);
        Arrays.sort(idsArr);
        String questionIds = JSON.toJSONString(idsArr);
        //查询对应的问卷
        Questionnaire q = questionnairesApi.findByProblemsId(questionIds);
        //查询用户的答案对应分数
        List<Answer> answerList = answerApi.findAnswerByIds(optionIds);
        //获取成绩区间
        Integer section = getSection(answerList);
        //生成维度
        String dimensions = generateDimension(answerList);
        //根据section level stars 获取personality
        Personality p = personalityApi.findPersonality(q.getLevel(), q.getStars(), section);
        //先判断数据库里是否存在
        Score score = scoreApi.findByCheckPointAndUserId(q.getLevel() * 10 + q.getStars(), UserHolder.getUser().getId());
        if (score != null) {
            //更新成绩
            score.setScore(section);
            //更新评分
            score.setPersonalityId(p.getId());
            score.setDimensions(dimensions);
            scoreApi.update(score);
            return personalityApi.findPersonality(score.getLevel(), score.getStars(), score.getScore()).getId().toString();
        }
        //填充score
        score = new Score();
        score.setScore(section);
        //当前关卡
        score.setCheckpoints(q.getLevel() * 10 + q.getStars());
        //级别
        score.setLevel(q.getLevel());
        //星级
        score.setStars(q.getStars());
        //维度
        score.setDimensions(dimensions);
        if (p == null) {
            p = new Personality();
            p.setId(1l);
        }
        score.setPersonalityId(p.getId());
        score.setUid(UserHolder.getUser().getId());
        scoreApi.save(score);
        return p.getId().toString();
    }

    /**
     * 生成维度
     *
     * @param answerList
     * @return
     */
    private String generateDimension(List<Answer> answerList) {
        //统计每个得分的出现次数
        Map<String, Integer> map = new HashMap<>();
        map.put("抽象", 0);
        map.put("判断", 0);
        map.put("外向", 0);
        map.put("理性", 0);
        answerList.forEach(answer -> {
                    if (answer.getScore() == 1) {
                        Integer count = map.get("抽象");
                        count = count + 1;
                        map.put("抽象", count);
                    } else if (answer.getScore() == 2) {
                        Integer count = map.get("判断");
                        count = count + 1;
                        map.put("判断", count);
                    } else if (answer.getScore() == 3) {
                        Integer count = map.get("外向");
                        count = count + 1;
                        map.put("外向", count);
                    } else if (answer.getScore() >= 4) {
                        Integer count = map.get("理性");
                        count = count + 1;
                        map.put("理性", count);
                    }
                }
        );
        List<DimensionsVo> list = new ArrayList<>();
        int index = 0;
        map.forEach((k, v) -> {
            DimensionsVo dimensionsVo = new DimensionsVo(k, v * 10 + "%");
            list.add(dimensionsVo);
        });
        DimensionsVo[] dimensionsVos = ArrayUtil.toArray(list, DimensionsVo.class);
        return JSON.toJSONString(dimensionsVos);
    }

    /**
     * 计算总分
     * 1-20 1 section
     * 21-40 2 section
     * 41-50 3 section
     */
    public Integer getSection(List<Answer> answerList) {
        Integer score = 0;
        for (Answer answer : answerList) {
            score += answer.getScore();//累加成绩
        }
        if (score >= 10 && score <= 20) {
            return 1;
        } else if (score >= 21 && score <= 40) {
            return 2;
        } else {
            return 3;
        }
    }


    /**
     * 查看结果
     */
    public PersonalityVo getReport(Long id) {
        //通过报告id查询报告
        Personality p = personalityApi.findById(id);
        //通过pid和用户id查询当前用户的成绩 level start
        Score condition = new Score();
        condition.setLevel(p.getLevel());
        condition.setStars(p.getStars());
        condition.setPersonalityId(p.getId());
        //通过成绩 ， pid level stars来查询和当前用户成绩一样用户集合
        List<Score> scores = scoreApi.findOneByCondition(condition);
        //抽取id
        List<Long> uids = new ArrayList<>();
        if (CollUtil.isEmpty(scores)) {
            //给个默认数据
            uids.add(106l);
            uids.add(45l);
        } else {
            uids = CollUtil.getFieldValues(scores, "uid", Long.class);
            uids.remove(UserHolder.getUser().getId());
        }
        //查询mysql
        if (CollUtil.isEmpty(uids)) {
            uids.add(106l);
        }
        List<UserInfo> userInfos = userInfoApi.findByIds(uids);
        //构造vo

        //查询当前用户的score
        Score score = scoreApi.findByUserIdAndCheckPoint(UserHolder.getUser().getId(), p.getLevel() * 10 + p.getStars());
        PersonalityVo vo = PersonalityVo.init(p, userInfos, score);
        //返回数据
        return vo;
    }
}

